#ifndef TRANSRADIX_H
#define TRANSRADIX_H

#include <stdio.h>
#include <stdlib.h>
#include "FFTEngine.h"
#include "Complex.h"
#include "CommLayer.h"

class TransRadix : public FFTEngine {

public:
	
	int *sendCounts;
	int *sendDisp;
	int *recvCounts;
	int *recvDisp;

	/** Constructors **/
	TransRadix(int iNumPoints, CommLayer *iComm) : FFTEngine(iNumPoints,iComm) {
		sendCounts = (int *) malloc(sizeof(int)*numNodes);
		sendDisp = (int *) malloc(sizeof(int)*numNodes);
		recvCounts = (int *) malloc(sizeof(int)*numNodes);
		recvDisp = (int *) malloc(sizeof(int)*numNodes);


		for (int i=0; i < numNodes; i++) { 
			sendCounts[i] = 2;
			recvCounts[i] = 2;
			sendDisp[i] = (numLocalPoints/numNodes) * i;
			recvDisp[i] = 2*i;
		}
	} 

	~TransRadix() {
		free(sendCounts);
		free(recvCounts);
		free(sendDisp);
		free(recvDisp);
	}


	/** FFT Driver functions
		uses distributeData(arr,isScatter,isCyclic,isBitReversed) 
	**/
	virtual void distributeInitData(Complex *arr) { distributeData(arr,true,true,false); }
	virtual void aquireInitData() { distributeData(NULL,true,true,false); }
	
	virtual void acquireResultData(Complex *arr) { distributeData(arr,false,false,true); }
	virtual void distributeResultData() { distributeData(NULL,false,false,true); }

	virtual void executeFFT(); //computes the FFT in localData
	virtual void executeFFT(bool onlyComm);

private:
	
	virtual bool isLocal(int globalId) { return blocked_globalNode(globalId) == rank; }
	virtual int global2localId(int globalId) { return blocked_global2localId(globalId); }	
	virtual int globalNode(int globalId) { return blocked_globalNode(globalId); }	


};
#endif
